#include<stdint.h>
#include<stdio.h>
#include <iostream>
#include <unordered_set>

using namespace std;

unordered_set<string>* str_pool;

const string* NewOrFindString(const string& s){
    auto f=str_pool->find(s);
    if(f==str_pool->end()){
        return &*str_pool->insert(s).first;
    }
    return &*f;
}


class ClassIter {
    private:
    FILE *fp;

    public:
    ClassIter(FILE *f) {
        fp = f;
    }

    uint16_t nextu2(){
        int res1 = (uint32_t)fgetc(fp);
        int res2 = (uint32_t)fgetc(fp);

        return res1 << 8 | res2;
    };

    uint32_t nextu4() {
        int res1 = (uint32_t)fgetc(fp);
        int res2 = (uint32_t)fgetc(fp);
        int res3 = (uint32_t)fgetc(fp);
        int res4 = (uint32_t)fgetc(fp);

        return res1 << 24 | res2 << 16 | res3 << 8 | res4;
    };

    uint32_t nextu1() {
        int res1 = (uint32_t)fgetc(fp);
        return res1;
    };

    uint8_t *nextuN(int n) {
        uint8_t *ptr = (uint8_t *) malloc(sizeof(uint8_t) * n);
        for(int i = 0; i < n; i++) {
            ptr[i] = fgetc(fp);
        }
        return ptr;
    };

    const string *nextuNString(const int n) {
        const int size = n + 1;
        char tmp[size];
        fread(tmp,1,n, fp);
        tmp[n] = '\0';
        return NewOrFindString(tmp);
    }

};